package com.ht.api.call.func.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import javax.sql.DataSource;

import com.ht.api.bean.AjaxResult;
import com.ht.api.bean.LoginBean;
import com.ht.api.call.func.IFunctionCall;
import com.ht.api.db.Db;
import com.ht.api.db.DbConfig;
import com.ht.api.db.DbList;
import com.ht.api.db.Entity;
import com.ht.api.db.util.RedisUtil;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;

/**
 * 获取分组信息
 * @author asq
 * @createTime 2025年2月17日 23:24:22
 */
@Slf4j
public class GroupInfoFunctionCall implements IFunctionCall {

	@Override
	public String getName() {
		return "获取分组信息";
	}

	@Override
	public JSONObject execute(LoginBean me, JSONObject param, AjaxResult result) {
		// 获取租户ID
		long tenantId = me.getTenantId();
		
		// 获取该租户的所有group表数据
		DbList groupEntityList = RedisUtil.get(tenantId + ":groups");
		
		// 获取参数
		String tagCode = param.getStr("tag_code");
		Integer status = param.getInt("status");
		List<String> groupIds = param.getBeanList("group_id", String.class);
		
		// 处理groupId参数
		List<String> groupIdList = null;
		if (groupIds == null || groupIds.isEmpty()) {
			// 未传group_id，则返回所有信息
			groupIdList = groupEntityList.stream().map(g -> g.getMainId()).toList();
		} else {
			// 根据groupIdList，查找所有的子结点以及孙子结点的groupId
			groupIdList = findChilds(groupEntityList, groupIds);
		}
		
		log.info("[GroupInfoFunctionCall]参数group_id:{}，最终group_id:{}", groupIds, groupIdList);
		
		// 生成sql参数
		StringBuilder args = new StringBuilder();
		for (int i = 0; i < groupIdList.size(); i++) {
			args.append("?,");
		}
		args.deleteCharAt(args.length() - 1);
		
		// 构造sql
		String sql = """
				SELECT
				  t.main_id,
				  t.tag_name,
				  t.tag_type,
				  t.tag_code,
				  t.rules,
				  t.remark,
				  t.`status`,
				  t.tag_color,
				  t.tag_icon,
				  tg.tag_group_name,
				  g.group_name,
				  g.main_id group_id,
				  tg.main_id tag_group_id 
				FROM `group` g
				  LEFT JOIN tag_group tg ON tg.group_id = g.main_id AND tg.sys_deleted = 1 %s
				  LEFT JOIN tag t ON t.tag_group_id = tg.main_id AND t.sys_deleted = 1
				WHERE g.main_id in(%s) and g.sys_deleted = 1 %s %s
				ORDER BY g.sys_time ASC, tg.sys_time ASC, t.sys_time ASC
				""";
		String tagCodeParam = StrUtil.isNotBlank(tagCode) ? "AND tg.tag_code=?" : "";
		String groupCodeParam = StrUtil.isNotBlank(tagCode) ? "AND g.group_code=?" : "";
		String statusParam = status != null ? "AND t.status=" + status : "";
		sql = String.format(sql, tagCodeParam, args, groupCodeParam, statusParam);
		
		// 获取查询参数
		List<String> params = new ArrayList<>();
		if (StrUtil.isNotBlank(tagCode)) {
			params.add(tagCode);
		}
		params.addAll(groupIdList);
		if (StrUtil.isNotBlank(tagCode)) {
			params.add("tag_group_" + tagCode);
		}
		
		// 查询
		DataSource ds = DbConfig.useTenantDb(tenantId);
		DbList list = Db.query(ds, sql, params);
		
		// 结果为空时作特殊处理
		if (list.isEmpty()) {
			String sql2 = "SELECT main_id group_id,group_name FROM `group` where main_id in(" + args + ")";
			List<String> params2 = new ArrayList<>(groupIdList);
			if (StrUtil.isNotBlank(tagCode)) {
				params2.add("tag_group_" + tagCode);
				sql2 += " and group_code=?";
			}
			DbList list2 = Db.query(ds, sql2, params2);
			return JSONUtil.createObj().set("list", list2);
		} else {
			// 组装
			JSONArray groupTags = groupTags(list);
			return JSONUtil.createObj().set("list", groupTags);
		}
	}
	
	private JSONArray groupTags(DbList tagList) {
	    // 2处理非空的数据
	    Map<String, Map<String, List<Entity>>> groupedTags = tagList.stream()
	            .filter(tag -> tag.getStr("tag_group_id") != null)  // 只处理非空的
	            .collect(Collectors.groupingBy(
	                    tag -> tag.getStr("group_id") + "," + tag.getStr("group_name"),
	                    Collectors.groupingBy(tag -> tag.getStr("tag_group_id") + "," + tag.getStr("tag_group_name"))
	            ));

	    JSONArray result = new JSONArray();

	    // 3. 处理分组数据
	    groupedTags.forEach((groupIdAndName, tagGroupMap) -> {
	        String[] groupArr = groupIdAndName.split(",");
	        JSONObject groupObject = new JSONObject();
	        groupObject.set("group_id", groupArr[0]);
	        groupObject.set("group_name", groupArr[1]);

	        JSONArray tagGroupsArray = new JSONArray();

	        tagGroupMap.forEach((tagGroupIdAndName, tags) -> {
	            // 去掉tags里面main_id为空的数据
	            List<Entity> validTags = tags.stream()
	                    .filter(tag -> tag.getStr("main_id") != null)
	                    .collect(Collectors.toList());

	            String[] tagGroupArr = tagGroupIdAndName.split(",");
	            JSONObject tagGroupObject = new JSONObject();
	            tagGroupObject.set("tag_group_id", tagGroupArr[0]);
	            tagGroupObject.set("tag_group_name", tagGroupArr[1]);
	            tagGroupObject.set("tags", validTags);
	            tagGroupsArray.put(tagGroupObject);
	        });

	        groupObject.set("tag_group", tagGroupsArray);
	        result.put(groupObject);
	    });
	    
	    // 再加上为null的没有数据的group数据
	    tagList.stream().filter(tag -> tag.getStr("tag_group_id") == null).forEach(tag -> {
	    	JSONObject groupObject = new JSONObject();
            groupObject.set("group_id", tag.getStr("group_id"));
            groupObject.set("group_name", tag.getStr("group_name"));
            groupObject.set("tag_group", new JSONArray());
            result.put(groupObject);
	    });

	    return result;
	}
	
	/**
	 * 根据多个groupId，从租户的group表数据中，查找所有子结点及孙子结点中的groupId
	 * @param groupEntityList 租户的group表数据
	 * @param groupIdList 多个groupId组成的列表
	 * @return
	 */
	private List<String> findChilds(DbList groupEntityList, List<String> groupIdList) {
		List<String> childGroupIds = new ArrayList<>();
		groupIdList.stream().forEach(b -> {
			childGroupIds.add(b);
			childGroupIds.addAll(findChilds(groupEntityList, b));
		});
		return childGroupIds;
	}

	/**
	 * 根据1个groupId，从租户的group表数据中，查找所有子结点及孙子结点中的groupId
	 * @param groupEntityList 租户的group表数据
	 * @param groupId
	 * @return
	 */
	private List<String> findChilds(DbList groupEntityList, String groupId) {
		List<String> childGroupIds = new ArrayList<>();
		for (Entity entity : groupEntityList) {
			if (groupId.equals(entity.getStr("parent_id"))) {
				String childGroupId = entity.getMainId();
				childGroupIds.add(childGroupId);
				childGroupIds.addAll(findChilds(groupEntityList, childGroupId));
			}
		}
		
		return childGroupIds;
	}
}
